home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / DIKUMUD.ZIP / PARSER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  3.6 KB  |  153 lines

  1. /*
  2.   SillyMUD Distribution V1.1b             (c) 1993 SillyMUD Developement
  3.  
  4.   See license.doc for distribution terms.   SillyMUD is based on DIKUMUD
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #include "protos.h" /* function prototypes for parser functions */
  11.  
  12. /* Sorted selection of the commands for quick lookup */
  13. struct radix_list radix_head[27];
  14.  
  15. /* Quick reference hash table */
  16. byte HashTable[256];
  17.  
  18. /* Command list is allocated at run-time in the following order:
  19. ** name, command pointer, number, min_position, min_level, next, previous.
  20. ** the number can be anything, it's no longer really needed, although
  21. ** it is recommended that you keep them in numeric order to avoid confusion.
  22. ** NOTE: next and previous MUST be defined as NULL to avoid any possible
  23. ** problems.
  24. */
  25.  
  26.  
  27. /* Adds a command to the Command List radix. */
  28. void AddCommand(char *name, void (*func), int number, int min_pos, int min_lev)
  29. {
  30.  NODE *n;
  31.  int len, radix;
  32.  
  33.  n = (NODE *) malloc(sizeof(NODE));
  34.  
  35.  n->name = (char *)strdup(name);
  36.  n->func = func;
  37.  n->number = number;
  38.  n->min_pos = min_pos;
  39.  n->min_level = min_lev;
  40.  n->next = NULL;
  41.  n->previous = NULL;
  42.  n->log = 0;
  43.  
  44.  radix = HashTable[*name];
  45.  len = strlen(name);
  46.  
  47.  AddNodeTail(n, len, radix);
  48. }
  49.  
  50.  
  51. /* Generates a hash table that assigns 1 - 26 to 'a' - 'z' and 'A' - 'Z'.
  52. ** All other results are 0
  53. */
  54. void GenerateHash()
  55. {
  56.  register int i;
  57.  
  58.  for(i = 0; i <= 255; i++)
  59.     if((i >= 'a') && (i <= 'z'))
  60.         HashTable[i] = i - MAGIC;
  61.     else if((i >= 'A') && (i <= 'Z'))
  62.         HashTable[i] = i - (MAGIC - 32);
  63.     else
  64.         HashTable[i] = 0;
  65. }
  66.  
  67.  
  68.  
  69. /* Adds a node to the end of a radix-sorted linked list.
  70. */
  71. void AddNodeTail(NODE *n, int length, int radix)
  72. {
  73.  /* Check to see if we're at the beginning, if so, start here. */
  74.  if(radix_head[radix].next == NULL) {
  75.     radix_head[radix].next = n;
  76.     radix_head[radix].number = 1;
  77.     radix_head[radix].max_len = length;
  78.     n->previous = NULL;
  79.     return;
  80.  }
  81.  
  82.  /* Traverse the list until we find the end, when we find it, add to it */
  83.  {
  84.   register NODE *i;
  85.  
  86.   for(i = radix_head[radix].next; i->next; i = i->next);
  87.   i->next = n;
  88.   n->previous = i;
  89.   radix_head[radix].number++;
  90.   n->next = NULL; 
  91.   if(radix_head[radix].max_len < length)
  92.      radix_head[radix].max_len = length;
  93.  }
  94. }
  95.  
  96.  
  97. /* This will search by name for a specific node and return a pointer to it.
  98. ** Passed is a pointer to the first node in the radix.  Any checking as to
  99. ** whether or not the node is valid should happen before entering here.
  100. ** NOTE: This uses partial matching, change strncmp to strcmp for full matching
  101. ** Return value is the node if it exists, or NULL if it does not.
  102. */
  103. NODE *SearchForNodeByName(NODE *head, char *name, int len)
  104. {
  105.  register NODE *i;
  106.  
  107.  i = head;
  108.  while(i) {
  109.     if(!(strncmp(i->name, name, len)))
  110.         return(i);
  111.     i = i->next;
  112.  }
  113.  
  114.  return(NULL);
  115. }
  116.  
  117.  
  118. /* Initialization for the radix sorting routines.  Call this to begin the sort.
  119. ** This will generate the hash table and sort everything via the hash-table.
  120. */
  121. void InitRadix()
  122. {
  123.  register int i;
  124.  
  125.  for(i = 0; i <= 26; i++) {
  126.     radix_head[i].next = NULL;
  127.     radix_head[i].number = 0;
  128.     radix_head[i].max_len = 0;
  129.  }
  130.  
  131.  GenerateHash();
  132.  
  133. }
  134.  
  135.  
  136. /* This will do all of the validation and search for a NODE by name.
  137. ** Will return a pointer to the NODE if it exists, NULL if it doesn't.
  138. */
  139. NODE *FindValidCommand(char *name)
  140. {
  141.  register int len;
  142.  register int radix;
  143.  
  144.  radix = HashTable[name[0]];
  145.  len = strlen(name);
  146.  
  147.  if(radix_head[radix].number && len <= radix_head[radix].max_len)
  148.     return(SearchForNodeByName(radix_head[radix].next, name, len));
  149.  
  150.  return(NULL);
  151. }
  152.  
  153.